/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller.XML;

import agh.rozproszony.model.Message;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 *
 * @author Seweryn
 */
public class MessagesXMLLocal {
    private final File Xfile;
    
    public MessagesXMLLocal(String pmFilePath)
    {
        System.out.println("Otwieranie pliku xml z wiadomosciami!");
        Xfile = new File(pmFilePath);
        if(!Xfile.exists())createFile();
        
    }
    
    
    public Message getMessage(int pmMessageId) {
        try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(Xfile);

            //optional, but recommended
            //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            NodeList nList = doc.getElementsByTagName("message");


            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);

                System.out.println("\nCurrent Element :" + nNode.getNodeName());

                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;
                   System.out.println("\nCurrent atribute :" + eElement.getAttribute("id"));
                    if (eElement.getAttribute("id").equals(Integer.toString(pmMessageId))) {
                        System.out.println("!!!!Wwarunku!!!!!");
                        int id = Integer.parseInt(eElement.getAttribute("id"));
                        String title = eElement.getElementsByTagName("title").item(0).getTextContent();
                        String content = eElement.getElementsByTagName("content").item(0).getTextContent();
                        int senderId = Integer.parseInt(eElement.getAttribute("senderid"));
                        int recipientId = Integer.parseInt(eElement.getAttribute("recipientid"));
                        int readed = Integer.parseInt(eElement.getAttribute("readed"));
                        return new Message(id, title, content, senderId, recipientId, readed);

                    }

               }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("!!!!Wiadomosci nie m a w XML!!!!!");
        return null;
    }
    /**
     * Zwraca ilość ostatnich wiadomości zdefiniowaną w parametrze
     * @param pmNumberOfMessages - ilość wiadomosci
     * @return 
     */
    public List<Message> getLastMessages(int pmNumberOfMessages)
    {
        List<Message> lvMes = new ArrayList<Message>();
          try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(Xfile);

            //optional, but recommended
            //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            NodeList nList = doc.getElementsByTagName("message");


              for (int temp = 0; temp < nList.getLength(); temp++) {

                  Node nNode = nList.item(temp);

                  System.out.println("\nCurrent Element :" + nNode.getNodeName());

                  if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                      Element eElement = (Element) nNode;

                      System.out.println("!!!!Wwarunku!!!!!");
                      int id = Integer.parseInt(eElement.getAttribute("id"));
                      String title = eElement.getElementsByTagName("title").item(0).getTextContent();
                      String content = eElement.getElementsByTagName("content").item(0).getTextContent();
                      int senderId = Integer.parseInt(eElement.getAttribute("senderid"));
                      int recipientId = Integer.parseInt(eElement.getAttribute("recipientid"));
                      int readed = Integer.parseInt(eElement.getAttribute("readed"));
                      lvMes.add(new Message(id, title, content, senderId, recipientId, readed));
                  }
              }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("!!!!Wiadomosci nie m a w XML!!!!!");
        List<Message> lvRet = lvMes.subList((lvMes.size()-pmNumberOfMessages)<0?0:(lvMes.size()-pmNumberOfMessages), lvMes.size());
        Collections.sort(lvRet, new Komparator());
        return lvRet;
    }
    
    public List<Message> getNotReadedMessages()
    {
        List<Message> lvMes = new ArrayList<Message>();
        try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(Xfile);

            //optional, but recommended
            //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            NodeList nList = doc.getElementsByTagName("message");


            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);

                System.out.println("\nCurrent Element :" + nNode.getNodeName());

                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;
                   System.out.println("\nCurrent atribute :" + eElement.getAttribute("id"));
                    if (eElement.getAttribute("readed").equals("2")) {
                        System.out.println("!!!!Wwarunku!!!!!");
                        int id = Integer.parseInt(eElement.getAttribute("id"));
                        String title = eElement.getElementsByTagName("title").item(0).getTextContent();
                        String content = eElement.getElementsByTagName("content").item(0).getTextContent();
                        int senderId = Integer.parseInt(eElement.getAttribute("senderid"));
                        int recipientId = Integer.parseInt(eElement.getAttribute("recipientid"));
                        int readed = Integer.parseInt(eElement.getAttribute("readed"));
                        lvMes.add(new Message(id, title, content, senderId, recipientId, readed));

                    }

               }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Collections.sort(lvMes, new Komparator());
        return lvMes;
    }
    
    public List<Message> getALLMessages()
    {
                List<Message> lvMes = new ArrayList<Message>();
          try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(Xfile);

            //optional, but recommended
            //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();


            NodeList nList = doc.getElementsByTagName("message");


              for (int temp = 0; temp < nList.getLength(); temp++) {

                  Node nNode = nList.item(temp);


                  if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                      Element eElement = (Element) nNode;

                      System.out.println("!!!!Wwarunku!!!!!");
                      int id = Integer.parseInt(eElement.getAttribute("id"));
                      String title = eElement.getElementsByTagName("title").item(0).getTextContent();
                      String content = eElement.getElementsByTagName("content").item(0).getTextContent();
                      int senderId = Integer.parseInt(eElement.getAttribute("senderid"));
                      int recipientId = Integer.parseInt(eElement.getAttribute("recipientid"));
                      int readed = Integer.parseInt(eElement.getAttribute("readed"));
                      lvMes.add(new Message(id, title, content, senderId, recipientId, readed));
                  }
              }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Collections.sort(lvMes,new Komparator());
        return lvMes;
    }
    public Boolean InsertMessage(Message pmMessage)
    {   
        return InsertMessage(pmMessage, 4);
        
    }
    public Boolean InsertMessage(Message pmMessage, int pmStatus)
    {
        
        
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder=null;
        try {
            docBuilder = docFactory.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
 
	// element glowny
	Document doc = null;
        try {
            doc = docBuilder.parse(Xfile);
        } catch (SAXException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        } catch (IOException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
        doc.getDocumentElement().normalize();
        if(pmStatus == 3)pmMessage.setReaded(pmStatus);
        //wpisanie wiadomosci w dokument
        doc = elementBuilder(doc, pmMessage);
                
        //Zapisanie wiadomości w pliku
        if(!documentSave(doc))return false;
                
                
        return true;
    }
    public Boolean InsertMessage(List<Message> pmListOfMessages)
    {
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder=null;
        try {
            docBuilder = docFactory.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
 
	// element glowny
	Document doc = null;
        try {
            doc = docBuilder.parse(Xfile);
        } catch (SAXException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        } catch (IOException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
        doc.getDocumentElement().normalize();
        //wpisanie wiadomosci w dokument
        for(Message lvMessage:pmListOfMessages)
        {
            doc = elementBuilder(doc, lvMessage);
        }
        
        //Zapisanie wiadomości w pliku
        if(!documentSave(doc))return false;
        
        return null;
    }
    private Document elementBuilder(Document pmDoc, Message pmMessage)
    {
        
        Element rootElement = pmDoc.getDocumentElement();
 
	// Poszczegolna wiadomosc
	Element lvMessageElement = pmDoc.createElement("message");
	rootElement.appendChild(lvMessageElement);
 
	// ustawienie atrybutu wiadomosci jako jej ID
	lvMessageElement.setAttribute("id", Integer.toString(pmMessage.getId()));
        lvMessageElement.setAttribute("senderid", Integer.toString(pmMessage.getSenderId()));
        lvMessageElement.setAttribute("recipientid", Integer.toString(pmMessage.getRecipientId()));
        lvMessageElement.setAttribute("readed", Integer.toString(pmMessage.getReaded()));
 
	// Wpisanie tytulu
	Element title = pmDoc.createElement("title");
	title.appendChild(pmDoc.createTextNode(pmMessage.getTitle()));
	lvMessageElement.appendChild(title);
        
        //wpisanie tresci wiadomosci
        Element content = pmDoc.createElement("content");
	content.appendChild(pmDoc.createTextNode(pmMessage.getContent()));
	lvMessageElement.appendChild(content);
        
        return pmDoc;
    }
    private Boolean documentSave(Document pmDoc)
    {
        try {
        
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(pmDoc);
		StreamResult result = new StreamResult(Xfile);
 
		// Output to console for testing
		// StreamResult result = new StreamResult(System.out);
 
		transformer.transform(source, result);
 
		System.out.println("File saved!");
 
	  } catch (TransformerException ex) {
            System.out.println("ERROR:MessagesXMLLocal->documentSave(): "+ex.toString());
            return false;
	  }
        return true;
    }
    private Boolean createFile()
    {
        try{
                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder=null;
                try {
                    docBuilder = docFactory.newDocumentBuilder();
                } catch (ParserConfigurationException ex) {
                    System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
                    return false;
                }
 
                // element glowny
                Document doc = docBuilder.newDocument();
                Element rootElement = doc.createElement("Inbox");
                doc.appendChild(rootElement);
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(doc);
		StreamResult result = new StreamResult(Xfile);
 
		// Output to console for testing
		// StreamResult result = new StreamResult(System.out);
 
		transformer.transform(source, result);
 
		System.out.println("File saved!");
 
	  } catch (TransformerException ex) {
            System.out.println("ERROR:MessagesXMLLocal->documentSave(): "+ex.toString());
            return false;
	  }
        return true;
    }
    public Boolean resetXML()
    {
        Xfile.delete();
        if(createFile()==true)return true;
        return false;
    }
        public List<Message> getNotSendMessages()
    {
        List<Message> lvMes = new ArrayList<Message>();
        try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(Xfile);

            //optional, but recommended
            //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            NodeList nList = doc.getElementsByTagName("message");


            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);


                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;
                    if (eElement.getAttribute("readed").equals("3")) {
                        int id = Integer.parseInt(eElement.getAttribute("id"));
                        String title = eElement.getElementsByTagName("title").item(0).getTextContent();
                        String content = eElement.getElementsByTagName("content").item(0).getTextContent();
                        int senderId = Integer.parseInt(eElement.getAttribute("senderid"));
                        int recipientId = Integer.parseInt(eElement.getAttribute("recipientid"));
                        int readed = Integer.parseInt(eElement.getAttribute("readed"));
                        lvMes.add(new Message(id, title, content, senderId, recipientId, readed));

                    }

               }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Collections.reverse(lvMes);
        return lvMes;
    }
    public Boolean changeStatus(int pmId, int pmStatus)
    {
        
        
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder=null;
        try {
            docBuilder = docFactory.newDocumentBuilder();
        } catch (ParserConfigurationException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
 
	// element glowny
	Document doc = null;
        try {
            doc = docBuilder.parse(Xfile);
        } catch (SAXException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        } catch (IOException ex) {
            System.out.println("ERROR:MessagesXMLLocal->insertMessage(): "+ex.toString());
            return false;
        }
        doc.getDocumentElement().normalize();        
        //wpisanie wiadomosci w dokument
                    NodeList nList = doc.getElementsByTagName("message");


            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);


                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;
                    if (eElement.getAttribute("id").equals(Integer.toString(pmId))) {
                       eElement.setAttribute("readed", Integer.toString(pmStatus));

                    }

               }
            }
                
        //Zapisanie wiadomości w pliku
        if(!documentSave(doc))return false;
                
                
        return true;
    }    
    
}
